package edu.cmu.cs.stage3.alice.authoringtool.editors.compositeeditor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool;
import edu.cmu.cs.stage3.alice.authoringtool.Editor;
import edu.cmu.cs.stage3.alice.authoringtool.event.AuthoringToolStateChangedEvent;
import edu.cmu.cs.stage3.alice.authoringtool.util.GroupingPanel;
import edu.cmu.cs.stage3.alice.core.Element;
import edu.cmu.cs.stage3.alice.core.event.PropertyEvent;
import edu.cmu.cs.stage3.alice.core.event.PropertyListener;
import edu.cmu.cs.stage3.swing.DialogManager;

// Referenced classes of package edu.cmu.cs.stage3.alice.authoringtool.editors.compositeeditor:
//            TempColorPicker, MainCompositeElementPanel, CompositeElementPanel

public abstract class CompositeElementEditor extends GroupingPanel implements Editor, PropertyListener {

private static int staticCont = 0;
private int cont = staticCont++;

 // edu/cmu/cs/stage3/alice/authoringtool/editors/responseeditor/ResponseEditor.java: estende 'CompositeElementEditor'
 // . ResponseEditor(): super();
 public CompositeElementEditor () {
  mainColor = Color.white;
  guiInit();
  addMouseListener(new MouseListener() {

   public void mouseClicked (MouseEvent e) {
    if ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0) {
     TempColorPicker tempColorPicker = new TempColorPicker( CompositeElementEditor.this );
     DialogManager.showMessageDialog( tempColorPicker );
     }
    }

   public void mousePressed(MouseEvent mouseevent) { }
   public void mouseEntered(MouseEvent mouseevent) {  }
   public void mouseExited(MouseEvent mouseevent) {  }
   public void mouseReleased(MouseEvent mouseevent) { }

   });
  }

 public MainCompositeElementPanel getMainPanel () {
  return compositeElementPanel;
  }

 //Rem @Override
 public void setBackground (Color backgroundColor) {
  super.setBackground(backgroundColor);
  if (compositeElementPanel != null)
   compositeElementPanel.setBackground(backgroundColor);
  }

 public JComponent getJComponent () {
  return this;
  }

 public Object getObject () {
  return elementBeingEdited;
  }

 public void setAuthoringTool (AuthoringTool authoringTool) {
  this.authoringTool = authoringTool;
  }

 protected abstract MainCompositeElementPanel createElementTree(Element element);

 protected abstract void initPrototypes();

 protected abstract void addPrototypes(Container container);

 protected abstract Color getEditorColor();

 // edu.cmu.cs.stage3.alice.authoringtool.util.EditorUtilities.getEditorFromClass(EditorUtilities.java:17)
 // edu.cmu.cs.stage3.alice.authoringtool.EditorManager.getEditorInstance(EditorManager.java:28)
 // edu.cmu.cs.stage3.alice.authoringtool.TabbedEditorComponent.editObject(TabbedEditorComponent.java:64)
 // edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool.editObject(AuthoringTool.java:738)
 protected void guiInit () {

  // try{String str=""; System.out.println(str.charAt(3));}catch(Exception e) {e.printStackTrace();}

  setBorder(null);
  removeAll();
  buttonPanel = new JPanel();
  Color buttonPanelColor = Color.white;
  buttonPanel.setOpaque(true);
  buttonPanel.setBackground(buttonPanelColor);
  buttonPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.gray));
  buttonPanel.setMinimumSize(new Dimension(0, 0));
  buttonPanel.setLayout(new FlowLayout(0) {

   //Rem @Override
   public Dimension preferredLayoutSize (Container target) {
    Insets insets = target.getParent().getInsets();
    int hgap = getHgap();
    int vgap = getVgap();
    int maxwidth = target.getParent().getWidth() - (insets.left + insets.right + hgap * 2);
    int nmembers = target.getComponentCount();
    int x = 0;
    int y = insets.top + vgap;
    int rowh = 0;
    target.getComponentOrientation().isLeftToRight();
    for (int i=0; i<nmembers; i++) {
     Component m = target.getComponent(i);
     if (!m.isVisible())
      continue;
     Dimension d = m.getPreferredSize();
     m.setSize(d.width, d.height);
     if (x == 0 || x + d.width <= maxwidth) {
      if (x > 0)
       x += hgap;
      x += d.width;
      rowh = Math.max(rowh, d.height);
     } else {
      x = d.width;
      y += vgap + rowh;
      rowh = d.height;
      }
     }

    return new Dimension(target.getParent().getWidth() - (insets.left + insets.right), y + rowh + vgap);
    }

   //Rem @Override
   public Dimension minimumLayoutSize(Container target) {
    return preferredLayoutSize(target);
   }

  });

  initPrototypes();
  addPrototypes(buttonPanel);
  new JScrollPane(buttonPanel, 20, 30);
  mainElementContainer = new JPanel();
  mainElementContainer.setLayout(new BorderLayout());
  mainElementContainer.setMinimumSize(new Dimension(0, 0));
  mainElementContainer.setBorder(null);
  mainElementContainer.setOpaque(false);
  mainElementContainer.setBackground(getEditorColor());
  setLayout(new BorderLayout());
  setBackground(getEditorColor());
  add(buttonPanel, "South");
  add(mainElementContainer, "Center");
  updateGui();
  }

 public void updateGui () {
  mainElementContainer.removeAll();
  if (elementBeingEdited != null && authoringTool != null) {
   clearAllListening();
   //System.out.println("CompositeElementEditor.java: #"+cont+" updateGui(): compositeElementPanel");

   // Chama: edu.cmu.cs.stage3.alice.authoringtool.editors.responseeditor.ResponseEditor.createElementTree(ResponseEditor.java:44)
   // Chamado: edu.cmu.cs.stage3.alice.authoringtool.editors.responseeditor.ResponseEditor.setObject(ResponseEditor.java:38)
   //          edu.cmu.cs.stage3.alice.authoringtool.editors.compositeeditor.CompositeElementEditor.worldLoaded(CompositeElementEditor.java:255)
   compositeElementPanel = createElementTree(elementBeingEdited); // abstract MainCompositeElementPanel compositeElementPanel

   if (compositeElementPanel != null) {
    mainElementContainer.add(compositeElementPanel, "Center");
    setBackground(compositeElementPanel.getBackground());
    }
  } else { // the first access to 'updateGui' enter here
   // System.out.println("CompositeElementEditor.java: #"+cont+" updateGui(): JPanel 'Not an editable element'");
   JLabel emptyLabel = new JLabel("Not an editable element");
   emptyLabel.setFont(emptyLabel.getFont().deriveFont(2));
   JPanel emptyPanel = new JPanel();
   emptyPanel.setLayout(new GridBagLayout());
   emptyPanel.setBackground(getBackground());
   emptyPanel.add(emptyLabel, new GridBagConstraints(0, 0, 1, 1, 0.0D, 0.0D, 10, 1, new Insets(0, 0, 0, 0), 0, 0));
   mainElementContainer.add(emptyPanel, "Center");
   }
  revalidate();
  repaint();
  }

 public static int getDepthCount (edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty children) {
  int maxDepth = 0;
  for (int i=0; i<children.size(); i++) {
   if (children.get(i) instanceof edu.cmu.cs.stage3.alice.core.response.CompositeResponse) {
    edu.cmu.cs.stage3.alice.core.response.CompositeResponse currentResponse = (edu.cmu.cs.stage3.alice.core.response.CompositeResponse)children.get(i);
    int depth = getDepthCount(currentResponse.componentResponses);
    if (depth > maxDepth) {
     maxDepth = depth;
     }
    if (currentResponse instanceof edu.cmu.cs.stage3.alice.core.response.IfElseInOrder) {
     edu.cmu.cs.stage3.alice.core.response.IfElseInOrder ifResponse = (edu.cmu.cs.stage3.alice.core.response.IfElseInOrder)currentResponse;
     depth = getDepthCount(ifResponse.elseComponentResponses);
     if (depth > maxDepth) {
      maxDepth = depth;
      }
     }
   } else if (children.get(i) instanceof edu.cmu.cs.stage3.alice.core.question.userdefined.Composite) {
    edu.cmu.cs.stage3.alice.core.question.userdefined.Composite currentQuestion = (edu.cmu.cs.stage3.alice.core.question.userdefined.Composite)children.get(i);
    int depth = getDepthCount(currentQuestion.components);
    if (depth > maxDepth) {
     maxDepth = depth;
    }
    if (currentQuestion instanceof edu.cmu.cs.stage3.alice.core.question.userdefined.IfElse) {
     edu.cmu.cs.stage3.alice.core.question.userdefined.IfElse ifQuestion = (edu.cmu.cs.stage3.alice.core.question.userdefined.IfElse)currentQuestion;
     depth = getDepthCount(ifQuestion.elseComponents);
     if (depth > maxDepth) {
      maxDepth = depth;
      }
     }
    }
   }
  return 1+maxDepth;
  }

 public void propertyChanging (PropertyEvent propertyevent) {}

 public void propertyChanged (PropertyEvent propertyevent) {}

 protected void clearAllListening () {
  if (compositeElementPanel != null)
   compositeElementPanel.clean();
   }

 public void stateChanging(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldLoading(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldUnLoading(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldStarting(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldStopping(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldPausing(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldSaving(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void stateChanged(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldLoaded (AuthoringToolStateChangedEvent ev) {
  updateGui();
  }

 public void worldUnLoaded(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldStarted(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldStopped(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldPaused(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}

 public void worldSaved(AuthoringToolStateChangedEvent authoringtoolstatechangedevent) {}


 public final String editorName = "Composite Editor";
 protected Element elementBeingEdited;
 protected MainCompositeElementPanel compositeElementPanel;
 protected JPanel mainElementContainer;
 protected JPanel buttonPanel;
 protected Color mainColor;
 protected AuthoringTool authoringTool;
 public static boolean IS_JAVA = false;

}
